﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Game1942.Library.Background;
using Game1942.Library.Background.Bodies;
using Game1942.Library.Controller;
using Game1942.Library.FlightPlans;
using Game1942.Library.Items;
using Game1942.Library.Weapons;

namespace Game1942.Library
{
    public class Algo42 : LivingElement
    {
        private EnergyCounter energy;
        private bool immune;
        private int amountOfRockets, amountOfTorpedos, lifes;

        // Constructor
        public Algo42()
        {
            energy = new EnergyCounter (Constants.Algo42.EnergyLimit);
            damage = Constants.Algo42.Damage;
            immune = false;
            amountOfRockets = amountOfTorpedos = 5;
            position.SetBody(new Square(Constants.Algo42.Width,Constants.Algo42.Height));
            playerTeam = Constants.Algo42.PlayerTeam;
            lifes = Constants.Algo42.Lifes;
        }

        public int Lifes
        {
            get { return lifes; }
            set { lifes = value; }
        }

		public void RelativeMove(Point relative)
        {
            position.Move(relative);
        }
        public override void CrashWith(Element intruder)
        {
            energy.Value = intruder.HarmSomebody(energy.Value);
            if (energy.Value == 0)
            {
                Destroy();
            }
        }

        public virtual bool InitializeLocation(Point point)
        {
            if ((object)point == null)
            {
                throw new ArgumentNullException("point", "The position cannot be null");
            }
            return (position.InitializeLocation(point));
        }

        public int AmountOfRockets
        {
            get { return amountOfRockets; }
            set { amountOfRockets = value; }
        }

        public int AmountOfTorpedos
        {
            get { return amountOfTorpedos; }
            set { amountOfTorpedos = value; }
        }

        //Destroy Algo42
        public override void Destroy()
        {
            Alive = false;
            position.Deallocate();
            lifes--;
        }

        //Immunity state setter flag
        public void SetImmunityState (bool anImmunityState)
        {
            immune = anImmunityState;
        }

        public int Energy
        {
            get { return energy.Value; }
            set { energy.Value = value; }
        }


        //Obtains the energy limit of algo42
        public int EnergyLimit
        {
            get { return Constants.Algo42.EnergyLimit; }
        }

        //Asked whether the subject is immune
        public bool Immune
        {
            get { return immune; }
        }


        //Reload the energy of algo42
        public void ReloadEnergy(EnergyTank anEnergyTank)
        {
            energy.Change(anEnergyTank.AmountOfEnergy);
        }

        //Reload weapons of algo42
        public void ReloadWeapons(AmmoPackage anAmmoPackage)
        {
            amountOfRockets = anAmmoPackage.AmountOfRockets;
            amountOfTorpedos = anAmmoPackage.AmountOfTorpedos;
        }

        //Moves right the Algo42
        public void MoveRight()
        {
            RelativeMove(new Point(Point.RightPoint));
        }

        //Moves left the Algo42
        public void MoveLeft()
        {
            RelativeMove(new Point(Point.LeftPoint));
        }

        //Moves up the Algo42
        public void MoveUp()
        {
            RelativeMove(new Point(Point.UpPoint));
        }

        //Moves down the Algo42
        public void MoveDown()
        {
            RelativeMove(new Point(Point.DownPoint));
        }

        //Fires a laser ammo
        public Ammo ShootLaser()
        {
            var offsetX = Constants.Algo42.Width/2 - Constants.Laser.Width/2;
            var laser = new Laser(new Point(ActualPosition.X + offsetX, ActualPosition.Y), playerTeam);
            Driver.Instance.AddLiveUnit(laser,Constants.Laser.Width,Constants.Laser.Height,Constants.Laser.ViewNameUp);
            return laser;
        }

        //Fires a rocket ammo
        public Ammo ShootRocket()
        {
            Ammo rocket =  null;
            if (amountOfRockets > 0)
            {
                var offsetX = Constants.Algo42.Width / 2 - Constants.Rocket.Width / 2;
                rocket = new Rocket(new Point(ActualPosition.X + offsetX, ActualPosition.Y), playerTeam);
                Driver.Instance.AddLiveUnit(rocket,Constants.Rocket.Width,Constants.Rocket.Height,Constants.Rocket.ViewNameUp);
                amountOfRockets--;
            }
            return rocket;
        }

        //Fires a torpedo ammo
        public Ammo ShootTorpedo()
        {
            Ammo torpedo = null;
            if (amountOfTorpedos > 0)
            {
                var offsetX = Constants.Algo42.Width / 2 - Constants.Rocket.Width / 2;
                torpedo = new Torpedo(new Point(ActualPosition.X + offsetX, ActualPosition.Y), playerTeam, false);
                Driver.Instance.AddLiveUnit(torpedo,Constants.Torpedo.Width,Constants.Rocket.Height,Constants.Torpedo.ViewNameUp);
                amountOfTorpedos--;
            }
            return torpedo;
        }
    }
}
